#ifndef HTTPMGR_H
#define HTTPMGR_H
#include "singleton.h"
#include <QString>
#include <QUrl>
#include <QObject>
//网络管理，需要到pro下增加network
/*
QT       += core gui network
*/
#include <QNetworkAccessManager>
// 序列化与反序列化
#include <QJsonObject>
#include <QJsonDocument>
/*
CRTP
可以看到他的基类有一个模版，明明他自己还没有实例化
却使用了自己的模板，这是否允许。
在CRTP这个技术中，他是允许的，因为泛型是在运行中识别
编译器发现你这样定义，会让你这样定义。
即奇异递归模板模式（Curiously Recurring Template Pattern）
*/
class HttpMgr:public QObject,
        public Singleton<HttpMgr>,
        //能够使用闭包的技术
        public std::enable_shared_from_this<HttpMgr>
{
 // 希望使用信号与槽，需要继承QObject和相关的宏
    Q_OBJECT

public:
    /*

    这里析构为什么要定义成公共的？
    【重点】
    我们的HttpMgr初始化会调用基类Singleton，因为我们定义的时候
    基类Singleton是protected,然后我们指定了一个=default的，所以这一步初始化
    是没问题的。
    然后，我们还定义了一个静态成员_instance,无论他的生命周期如何，当Singleton销毁时
    _instance也会被回收，由于我们使用智能指针std::shared_ptr<HtpMgr>持有了_instance
    回收也相当于调用了shared_ptr的析构，他调用又会调用模版中的T的析构，在这里就是HttpMgr
    所以就是现在的这个方法，为了保证能够父类能够访问，所以这里析构定义为公共的
    */
    ~HttpMgr();

    /**
     * 以post方式发送请求
     * @brief PostHttpReq
     * @param url 发送的url
     * @param json 发送的序列化完成json数据
     * @param req_id 这次请求的id，方便追踪
     * @param mod 发送的模块，发送到哪里
     */
    void PostHttpReq(QUrl url,
                     QJsonObject json,
                     ReqId req_id,
                     Modules mod);

private:
    /*
//【类做友元】
// 这个类可以访问本类中私有的成员
和上述的析构不同，由于本来是一个单例，所以构造方法没办法公共
在getInstance中，又要调用子类的构造函数初始化，所以这里使用友元。保证可以访问该类的私有属性
    */
    friend class Singleton<HttpMgr>;
    //因为单例，所以是私有
    HttpMgr();

    QNetworkAccessManager _manager;



private slots:
    //槽函数和信号参数保持一致？
    void slot_http_finish(ReqId id,
                          QString res,
                          ErrorCodes err,
                          Modules mod);
signals:
    /**
      表示发送http的信号，接到信号会在界面上做显示
     * @brief sig_http_finish
     * @param id 是什么功能的id
     * @param res 返回结果
     * @param err 错误信息
     * @param mod 发送什么模块
     */
    void sig_http_finish(
            ReqId id,
            QString res,
            ErrorCodes err,
            Modules mod);

    void sig_reg_mod_finish(
            ReqId id,
            QString res,
            ErrorCodes err);

    void sig_reset_mod_finish(ReqId id,
                              QString res,
                              ErrorCodes err);
    void sig_login_mod_finish(ReqId id,
                              QString res,
                              ErrorCodes err);

};

#endif // HTTPMGR_H
